import jieba
import re
import matplotlib.pyplot as plt
from collections import defaultdict
import numpy as np

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 主题关键词定义
TOPIC_KEYWORDS = {
    "家族兴衰": ["贾府", "家族", "兴衰", "荣宁", "富贵", "衰落", "门第", "世家", "祖业", "败落", "家业", "宗祠", "祠堂", "家庙", "府邸"],
    "爱情悲剧": ["宝玉", "黛玉", "宝钗", "爱情", "婚姻", "情感", "相思", "缘分", "情缘", "痴情", "眼泪", "心事", "情思", "思虑", "离别"],
    "宗教哲学": ["僧道", "佛法", "道家", "空门", "红尘", "因果", "轮回", "觉悟", "禅机", "出世", "神仙", "道士", "和尚", "禅宗", "佛理"],
    "社会批判": ["官场", "权贵", "腐败", "世态", "炎凉", "人情", "冷暖", "仕途", "功名", "富贵", "贪官", "污吏", "豪门", "势利", "攀附"],
    "女性命运": ["女子", "女儿", "闺阁", "命运", "薄命", "红颜", "才女", "佳人", "美人", "香消", "红颜", "裙钗", "脂粉", "金钗", "香魂"]
}

def read_redology_text(file_path='temp.txt'):
    """读取红楼梦文本"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        print(f"文件 {file_path} 未找到，请确认文件路径是否正确")
        return None

def split_into_chapters(text):
    """将文本按章节分割"""
    # 使用章节标题分割文本
    pattern = r'第[一二三四五六七八九十百千]+回[^\n]*\n'
    chapters = re.split(pattern, text)
    # 移除第一个可能的空元素
    if chapters and not chapters[0].strip():
        chapters = chapters[1:]
    return chapters

def count_topic_words(text, topic_keywords):
    """统计文本中主题关键词的出现次数"""
    word_count = 0
    words = jieba.lcut(text)
    for word in words:
        if word in topic_keywords:
            word_count += 1
    return word_count

def analyze_topic_evolution(text):
    """分析各主题随章节的发展变化"""
    # 分割章节
    chapters = split_into_chapters(text)
    print(f"共分割出 {len(chapters)} 个章节")
    
    # 初始化主题计数
    topic_trends = defaultdict(list)
    
    # 分析每个章节的主题词频
    for i, chapter in enumerate(chapters):
        # 每5回作为一个分析单位，减少数据点数量
        if i % 5 != 0 and i != len(chapters) - 1:
            continue
            
        for topic, keywords in TOPIC_KEYWORDS.items():
            count = count_topic_words(chapter, keywords)
            topic_trends[topic].append(count)
    
    return topic_trends, list(range(1, len(chapters)+1, 5))[:len(topic_trends["家族兴衰"])]

def plot_topic_evolution(topic_trends, chapters):
    """绘制主题演变趋势图"""
    plt.figure(figsize=(14, 8))
    
    # 为每个主题绘制趋势线
    for topic, counts in topic_trends.items():
        plt.plot(chapters[:len(counts)], counts, marker='o', linewidth=2, label=topic, markersize=5)
    
    plt.xlabel('章节 (回)', fontsize=12)
    plt.ylabel('主题词频', fontsize=12)
    plt.title('《红楼梦》各主题随章节发展变化趋势', fontsize=16, fontweight='bold')
    plt.legend(fontsize=10, loc='upper left')
    plt.grid(True, alpha=0.3)
    
    # 设置x轴刻度
    if len(chapters) > 10:
        step = len(chapters) // 10
        plt.xticks(chapters[::step], [f'第{chap}回' for chap in chapters[::step]], rotation=45)
    else:
        plt.xticks(chapters, [f'第{chap}回' for chap in chapters], rotation=45)
    
    plt.tight_layout()
    
    # 保存图像
    plt.savefig('红楼梦主题演化趋势.png', dpi=300, bbox_inches='tight')
    plt.show()
    print("主题演变趋势图已保存为 红楼梦主题演化趋势.png")

def main():
    print("《红楼梦》主题演变趋势分析")
    print("=" * 40)
    
    # 读取文本
    text = read_redology_text()
    if text is None:
        return
    
    try:
        # 分析主题演变
        topic_trends, chapter_numbers = analyze_topic_evolution(text)
        
        # 显示分析结果
        print("\n各主题词频统计:")
        print("-" * 50)
        for topic, counts in topic_trends.items():
            print(f"{topic}: 总计 {sum(counts)} 次")
        
        # 绘制主题演变趋势图
        plot_topic_evolution(topic_trends, chapter_numbers)
        
    except Exception as e:
        print(f"分析过程中出现错误: {e}")

if __name__ == "__main__":
    main()